﻿using System.Diagnostics.CodeAnalysis;
using System.Net.Http.Json;
using BPM.Web.Shared.Data;
using BPM.Web.Shared.Extensions;

namespace BPM.Web.Shared.Service
{
    public class HttpManager : IHttpManager
    {
        private readonly JsonSerializerProvider _json;
        private readonly HttpClient _client;

        public HttpManager(JsonSerializerProvider json, HttpClient client)
        {
            _json = json;
            _client = client;
        }

        public void ClearClientAuthorization()
        {
            _client.DefaultRequestHeaders.Authorization = null;
        }

        public async Task PostAsync<T>(string url, T request)
        {
            await Handle<string>(() => _client.PostAsJsonAsync(url, request));
        }

        public async Task<XnRestfulResult<T2>> PostAsync<T1, T2>(string url, T1 request)
        {
            return await Handle<T2>(() => _client.PostAsJsonAsync(url, request));
        }

        public async Task<XnRestfulResult<T2>> GetAsync<T1, T2>(string url, T1 paras)
        {
            return await Handle<T2>(() => _client.GetAsync(url.AddQueryString(paras?.ToDict())));
        }

        public async Task<XnRestfulResult<T>> GetAsync<T>(string url, IEnumerable<KeyValuePair<string, object>>? paras = null)
        {
            return await Handle<T>(() => _client.GetAsync(url.AddQueryString(paras)));
        }

        public async Task<XnRestfulResult<T>> DeleteAsync<T>(string url, IEnumerable<KeyValuePair<string, object>>? paras = null)
        {
            return await Handle<T>(() => _client.DeleteAsync(url.AddQueryString(paras)));
        }

        public async Task<XnRestfulResult<T2>> PutAsync<T1, T2>(string url, T1 request)
        {
            return await Handle<T2>(() => _client.PutAsJsonAsync(url, request));
        }

        private async Task<XnRestfulResult<T>> Handle<T>([NotNull] Func<Task<HttpResponseMessage>> func)
        {
            var result = new XnRestfulResult<T>() { Message = "操作失败，请重试。" };
            try
            {
                var response = await func.Invoke();
                result.Code = (int)response.StatusCode;
                switch (response.StatusCode)
                {
                    case System.Net.HttpStatusCode.Unauthorized:
                        result.Message = "验证已过期，请重新登录！";
                        break;
                    case System.Net.HttpStatusCode.Forbidden:
                        result.Message = "没有访问权限，请联系管理员配置。";
                        break;
                    case System.Net.HttpStatusCode.OK:
                        {
                            var res = await response.Content.ReadFromJsonAsync<XnRestfulResult<T>>(_json.ReadOptions);
                            if (res != null)
                            {
                                return res;
                            }
                            else result.Message = await response.Content.ReadAsStringAsync();
                            break;
                        };
                }
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return result;
        }
    }
}
